/**
 * @flow
 */
import React,{Component} from 'react';
import {
    Animated,
    CameraRoll,
    I18nManager,
    Image,
    Text,
    TouchableHighlight,
    TouchableOpacity,
    TouchableWithoutFeedback,
    View,
    StyleSheet,
    Platform
} from "react-native";
import PropTypes,{string,number} from 'prop-types';
import ImageZoom from "./ImageZoom.js";
import Label from '../label/index';
import Calculate from '../../config/calculate.js';


export default class ImageViewer extends Component{
    constructor(props) {
        super(props);
        this.state = {
            show: false,
            prevPropsCurrentShowIndex: 0,
            currentShowIndex: 0,
            imageLoaded:false,
            imageSizes:[],
            isShowMenu:false
        }
    }
    // 背景透明度渐变动画
    fadeAnim = new Animated.Value(0);

    // 当前基准位置
    standardPositionX = 0;

    // 整体位移，用来切换图片用
    positionXNumber = 0;
    positionX = new Animated.Value(0);

    width = 0;
    height = 0;

    styles = styles(0, 0, "transparent");

    // 是否执行过 layout. fix 安卓不断触发 onLayout 的 bug
    hasLayout = false;

    // 记录已加载的图片 index
    loadedIndex = new Map();

    handleLongPressWithIndex = new Map();

    componentDidMount() {
        this.init(this.props);
    }

    static getDerivedStateFromProps(nextProps, prevState) {
        if (('index' in nextProps) && (nextProps.index !== prevState.prevPropsCurrentShowIndex)) {
            return {
                prevPropsCurrentShowIndex: nextProps.index,
                currentShowIndex: nextProps.index
            };
        }
        return null;
    }

    componentDidUpdate(){
        this.loadImage(this.props.index || 0);

        this.jumpToCurrentImage();

        // 显示动画
        Animated.timing(this.fadeAnim, {
            toValue: 1,
            duration: 200
        }).start();
    }

    /**
     * props 有变化时执行
     */
    init(nextProps) {
        if (nextProps.imageUrls.length === 0) {
            // 隐藏时候清空
            this.fadeAnim.setValue(0);
            return this.setState(new State());
        }

        // 给 imageSizes 塞入空数组
        const imageSizes = [];
        nextProps.imageUrls.forEach(imageUrl => {
            imageSizes.push({
                width: imageUrl.width || 0,
                height: imageUrl.height || 0,
                status: "loading"
            });
        });

        this.setState(
            {
                currentShowIndex: nextProps.index,
                imageSizes
            },
            () => {
                // 立刻预加载要看的图
                this.loadImage(nextProps.index || 0);

                this.jumpToCurrentImage();

                // 显示动画
                Animated.timing(this.fadeAnim, {
                    toValue: 1,
                    duration: 200
                }).start();
            }
        );
    }

    /**
     * 调到当前看图位置
     */
    jumpToCurrentImage() {
        // 跳到当前图的位置
        this.positionXNumber = -this.width * (this.state.currentShowIndex || 0);
        this.standardPositionX = this.positionXNumber;
        this.positionX.setValue(this.positionXNumber);
    }

    /**
     * 加载图片，主要是获取图片长与宽
     */
    loadImage(index) {
        if (!this.state.imageSizes[index]) {
            return;
        }

        if (this.loadedIndex.has(index)) {
            return;
        }
        this.loadedIndex.set(index, true);

        const image = this.props.imageUrls[index];
        const imageStatus = { ...this.state.imageSizes[index] };

        // 保存 imageSize
        const saveImageSize = () => {
            // 如果已经 success 了，就不做处理
            if (
                this.state.imageSizes[index] &&
                this.state.imageSizes[index].status !== "loading"
            ) {
                return;
            }

            const imageSizes = this.state.imageSizes.slice();
            imageSizes[index] = imageStatus;
            this.setState({ imageSizes });
        };

        if (this.state.imageSizes[index].status === "success") {
            // 已经加载过就不会加载了
            return;
        }

        // 如果已经有宽高了，直接设置为 success
        if (
            this.state.imageSizes[index].width > 0 &&
            this.state.imageSizes[index].height > 0
        ) {
            imageStatus.status = "success";
            saveImageSize();
            return;
        }

        // 是否加载完毕了图片大小
        const sizeLoaded = false;
        // 是否加载完毕了图片
        let imageLoaded = false;

        if (!image.url || image.url.startsWith(`file:`)) {
            imageLoaded = true;
            try {
                const data = Image.resolveAssetSource(image.props.source);
                imageStatus.width = data.width;
                imageStatus.height = data.height;
                imageStatus.status = "success";
                saveImageSize();
            } catch (newError) {
                // Give up..
                imageStatus.status = "fail";
            }
        }else{
            Image.getSize(
                image.url,
                (width, height) => {
                    imageStatus.width = width;
                    imageStatus.height = height;
                    imageStatus.status = "success";
                    saveImageSize();
                },
                error => {
                    try {
                        const data = Image.resolveAssetSource(image.props.source);
                        imageStatus.width = data.width;
                        imageStatus.height = data.height;
                        imageStatus.status = "success";
                        saveImageSize();
                    } catch (newError) {
                        // Give up..
                        imageStatus.status = "fail";
                    }
                }
            )
        }
    }

    /**
     * 触发溢出水平滚动
     */
    handleHorizontalOuterRangeOffset = (offsetX) => {
        this.positionXNumber = this.standardPositionX + offsetX;
        this.positionX.setValue(this.positionXNumber);

        const offsetXRTL = !I18nManager.isRTL ? offsetX : -offsetX;

        if (offsetXRTL < 0) {
            if (
                this.state.currentShowIndex ||
            0 < this.props.imageUrls.length - 1
        ) {
                this.loadImage((this.state.currentShowIndex || 0) + 1);
            }
        } else if (offsetXRTL > 0) {
            if (this.state.currentShowIndex || 0 > 0) {
                this.loadImage((this.state.currentShowIndex || 0) - 1);
            }
        }
    };

    /**
     * 手势结束，但是没有取消浏览大图
     */
    handleResponderRelease = (vx) => {
        const vxRTL = I18nManager.isRTL ? -vx : vx;
        const isLeftMove = I18nManager.isRTL
            ? this.positionXNumber - this.standardPositionX <
            -(this.props.flipThreshold || 0)
            : this.positionXNumber - this.standardPositionX >
            (this.props.flipThreshold || 0);
        const isRightMove = I18nManager.isRTL
            ? this.positionXNumber - this.standardPositionX >
            (this.props.flipThreshold || 0)
            : this.positionXNumber - this.standardPositionX <
            -(this.props.flipThreshold || 0);

        if (vxRTL > 0.7) {
            // 上一张
            this.goBack.call(this);

            // 这里可能没有触发溢出滚动，为了防止图片不被加载，调用加载图片
            if (this.state.currentShowIndex || 0 > 0) {
                this.loadImage((this.state.currentShowIndex || 0) - 1);
            }
            return;
        } else if (vxRTL < -0.7) {
            // 下一张
            this.goNext.call(this);
            if (this.state.currentShowIndex || 0 < this.props.imageUrls.length - 1) {
                this.loadImage((this.state.currentShowIndex || 0) + 1);
            }
            return;
        }

        if (isLeftMove) {
            // 上一张
            this.goBack.call(this);
        } else if (isRightMove) {
            // 下一张
            this.goNext.call(this);
            return;
        } else {
            // 回到之前的位置
            this.resetPosition.call(this);
            return;
        }
    };

    /**
     * 到上一张
     */
    goBack = () => {
        if (this.state.currentShowIndex === 0) {
            // 回到之前的位置
            this.resetPosition.call(this);
            return;
        }

        this.positionXNumber = !I18nManager.isRTL
            ? this.standardPositionX + this.width
            : this.standardPositionX - this.width;
        this.standardPositionX = this.positionXNumber;
        Animated.timing(this.positionX, {
            toValue: this.positionXNumber,
            duration: 100
        }).start();

        const nextIndex = (this.state.currentShowIndex || 0) - 1;

        this.setState(
            {
                currentShowIndex: nextIndex
            },
            () => {
                if (this.props.onChange) {
                    this.props.onChange(this.state.currentShowIndex);
                }
            }
        );
    };

    /**
     * 到下一张
     */
    goNext() {
        if (this.state.currentShowIndex === this.props.imageUrls.length - 1) {
            // 回到之前的位置
            this.resetPosition.call(this);
            return;
        }

        this.positionXNumber = !I18nManager.isRTL
            ? this.standardPositionX - this.width
            : this.standardPositionX + this.width;
        this.standardPositionX = this.positionXNumber;
        Animated.timing(this.positionX, {
            toValue: this.positionXNumber,
            duration: 100
        }).start();

        const nextIndex = (this.state.currentShowIndex || 0) + 1;

        this.setState(
            {
                currentShowIndex: nextIndex
            },
            () => {
                if (this.props.onChange) {
                    this.props.onChange(this.state.currentShowIndex);
                }
            }
        );
    }

    /**
     * 回到原位
     */
    resetPosition() {
        this.positionXNumber = this.standardPositionX;
        Animated.timing(this.positionX, {
            toValue: this.standardPositionX,
            duration: 150
        }).start();
    }

    /**
     * 长按
     */
    handleLongPress = (image) => {
        if (this.props.saveToLocalByLongPress) {
            // 出现保存到本地的操作框
            this.setState({ isShowMenu: true });
        }

        if (this.props.onLongPress) {
            this.props.onLongPress(image);
        }
    };

    /**
     * 单击
     */
    handleClick = () => {
        if (this.props.onClick) {
            this.props.onClick(this.handleCancel);
        }
    };

    /**
     * 双击
     */
    handleDoubleClick = () => {
        if (this.props.onDoubleClick) {
            this.props.onDoubleClick(this.handleCancel);
        }
    };

    /**
     * 退出
     */
    handleCancel = () => {
        this.hasLayout = false;
        if (this.props.onCancel) {
            this.props.onCancel();
        }
    };

    /**
     * 完成布局
     */
    handleLayout = (event) => {
        if(event.nativeEvent.layout.width != this.width) {
            this.hasLayout = true;

            this.width = event.nativeEvent.layout.width;
            this.height = event.nativeEvent.layout.height;
            this.styles = styles(
                this.width,
                this.height,
                this.props.backgroundColor || "transparent"
            );

            // 强制刷新
            this.forceUpdate();
            this.jumpToCurrentImage();
        }
    };

    /**
     * 获得整体内容
     */
    getContent() {
        // 获得屏幕宽高
        const screenWidth = this.width;
        const screenHeight = this.height;

        const ImageElements = this.props.imageUrls.map((image, index) => {
            if (
                (this.state.currentShowIndex || 0) > index + 1 ||
                (this.state.currentShowIndex || 0) < index - 1
            ) {
                return (
                    <View
                        key={index}
                        style={{ width: screenWidth, height: screenHeight }}
                    />
                );
            }

            if (!this.handleLongPressWithIndex.has(index)) {
                this.handleLongPressWithIndex.set(
                    index,
                    this.handleLongPress.bind(this, image)
                );
            }

            let width =
                this.state.imageSizes[index] &&
                this.state.imageSizes[index].width;
            let height =
                this.state.imageSizes[index] && this.state.imageSizes[index].height;
            const imageInfo = this.state.imageSizes[index];

            if (!imageInfo || !imageInfo.status) {
                return (
                    <View
                        key={index}
                        style={{ width: screenWidth, height: screenHeight }}
                    />
                );
            }

            // 如果宽大于屏幕宽度,整体缩放到宽度是屏幕宽度
            if (width > (screenWidth)) {
                if(width == 0){
                    width = 0;
                    height = 0;
                }else{
                    const widthPixel = screenWidth / width;
                    width *= widthPixel;
                    height *= widthPixel;
                }
            }

            // 如果此时高度还大于屏幕高度,整体缩放到高度是屏幕高度
            if (height > screenHeight  - 90) {
                if(height == 0){
                    width = 0;
                    height = 0;
                }else{
                    const HeightPixel = Calculate.isIphoneX() ? (screenHeight - 94) / height : (screenHeight  - 90) / height;
                    width *= HeightPixel;
                    height *= HeightPixel;
                }
            }

            const Wrapper = ({ children, ...others }) => (
                <ImageZoom
                    cropWidth={this.width}
                    cropHeight={this.height}
                    maxOverflow={this.props.maxOverflow}
                    horizontalOuterRangeOffset={this.handleHorizontalOuterRangeOffset}
                    responderRelease={this.handleResponderRelease}
                    onLongPress={this.handleLongPressWithIndex.get(index)}
                    onClick={this.handleClick}
                    onDoubleClick={this.handleDoubleClick}
                    enableSwipeDown={false}
                    onSwipeDown={this.handleSwipeDown}
                    {...others}
                >
                    {children}
                </ImageZoom>
            );

            switch (imageInfo.status) {
                case "loading":
                    return (
                        <Wrapper
                            key={index}
                            style={{
                                ...this.styles.modalContainer,
                                ...this.styles.loadingContainer
                            }}
                            imageWidth={screenWidth}
                            imageHeight={screenHeight}
                        >
                            <View style={this.styles.loadingContainer}>
                                {this.props.loadingRender()}
                            </View>
                        </Wrapper>
                    );
                case "success":
                    if (!image.props) {
                        image.props = {};
                    }

                    if (!image.props.style) {
                        image.props.style = {};
                    }
                    image.props.style = {
                        ...this.styles.imageStyle,
                        // User config can override above.
                        ...image.props.style,
                        width: width,
                        height: height
                    };

                    if (typeof image.props.source === "number") {
                        // source = require(..), doing nothing
                    } else {
                        if (!image.props.source) {
                            image.props.source = {};
                        }
                        image.props.source = {
                            uri: image.url,
                            ...image.props.source
                        };
                    }

                    // finalProps.source = { uri: image.url, ...finalProps.source };

                    return (
                        <ImageZoom
                            key={index}
                            cropWidth={this.width}
                            cropHeight={this.height}
                            maxOverflow={this.props.maxOverflow}
                            horizontalOuterRangeOffset={this.handleHorizontalOuterRangeOffset}
                            responderRelease={this.handleResponderRelease}
                            onLongPress={this.handleLongPressWithIndex.get(index)}
                            onClick={this.handleClick}
                            onDoubleClick={this.handleDoubleClick}
                            imageWidth={width}
                            imageHeight={height}
                            enableSwipeDown={false}
                            onSwipeDown={this.handleSwipeDown}
                        >
                            {this.props.renderImage(image.props)}
                        </ImageZoom>
                    );
                case "fail":
                    return (
                        <Wrapper
                            key={index}
                            style={this.styles.modalContainer}
                            imageWidth={
                                this.props.failImageSource
                                    ? this.props.failImageSource.width
                                    : screenWidth
                            }
                            imageHeight={
                                this.props.failImageSource
                                    ? this.props.failImageSource.height
                                    : screenHeight
                            }
                        >
                            {this.props.failImageSource && (
                                this.props.renderImage({
                                source: {
                                uri: this.props.failImageSource.url || this.props.failImageSource.source
                            },
                                style: {
                                width: this.props.failImageSource.width,
                                height: this.props.failImageSource.height
                            }
                            })
                                )}
                        </Wrapper>
                    );
            }
        });

        let footerStyles = [simpleStyle.footer];
        if(Calculate.isIphoneX()){
            footerStyles.push({bottom:20});
        }
        return (
            <Animated.View style={{ zIndex: 99 }}>
                <Animated.View
                    style={{ ...this.styles.container, opacity: this.fadeAnim }}
                >
                    <View style={[this.styles.headerContainer, Platform.OS == 'harmony' &&{ zIndex:1 }]}>
                        {this.props.renderHeader(this.state.currentShowIndex)}
                    </View>

                    <View style={[this.styles.arrowLeftContainer, Platform.OS == 'harmony' &&{ zIndex:1 }]}>
                        <TouchableWithoutFeedback onPress={this.goBack}>
                            <View>{this.props.renderArrowLeft()}</View>
                        </TouchableWithoutFeedback>
                    </View>

                    <View style={[this.styles.arrowRightContainer, Platform.OS == 'harmony' &&{ zIndex:1 }]}>
                        <TouchableWithoutFeedback onPress={this.goNext}>
                            <View>{this.props.renderArrowRight()}</View>
                        </TouchableWithoutFeedback>
                    </View>

                    <Animated.View
                        style={{
                            ...this.styles.moveBox,
                            transform: [{ translateX: this.positionX }],
                            width: this.width * this.props.imageUrls.length
                        }}
                    >
                        {ImageElements}
                    </Animated.View>
                    {this.props.renderIndicator(
                        (this.state.currentShowIndex || 0) + 1,
                        this.props.imageUrls.length,
                        this.props.imageUrls[this.state.currentShowIndex || 0].fileName
                        )}

                    {this.props.imageUrls[this.state.currentShowIndex || 0] &&
                    this.props.imageUrls[this.state.currentShowIndex || 0]
                        .originSizeKb &&
                    this.props.imageUrls[this.state.currentShowIndex || 0]
                        .originUrl && (
                        <View style={[this.styles.watchOrigin, Platform.OS == 'harmony' &&{ zIndex:1 }]}>
                            <TouchableOpacity style={this.styles.watchOriginTouchable}>
                                <Label labelStyle={[this.styles.watchOriginText]} type={'form'} color={'navbar'}  text={'查看原图(2M)'} />
                            </TouchableOpacity>
                        </View>
                    )}
                    <View
                        style={[footerStyles,
                            this.props.footerContainerStyle
                        ]}
                    >
                        <View style={{flex:1,backgroundColor:'transparent'}}>
                            {this.props.renderFooter(this.state.currentShowIndex)}
                        </View>
                        <View style={this.styles.saveContainer}>
                            <TouchableWithoutFeedback onPress={()=>{this.setState({ isShowMenu: true })}}>
                                <Image source={require('../../assets/imageViewer_save.png')} style={{height:25,width:25,resizeMode:'contain'}}/>
                            </TouchableWithoutFeedback>
                        </View>
                    </View>
                </Animated.View>
            </Animated.View>
        );
    }

    deleteCacheImage=(path)=> {
        const RNFetchBlob = require("rn-fetch-blob").default
        RNFetchBlob.fs.unlink(path).then(() => {
            //console.warn('Deleted successfully')
        })
    }

    /**
     * 保存当前图片到本地相册
     */
    saveToLocal = () => {
        let url = this.props.imageUrls[this.state.currentShowIndex || 0].url;
        if(Platform.OS === 'android' && url.length > 0){
            const RNFetchBlob = require("rn-fetch-blob").default
            RNFetchBlob
                .config({
                    fileCache: true,
                    appendExt: 'png',
                    timeout: 600000    //设置超时时间
                })
                .fetch('GET', url, {
                    'Accept': '*/*',
                    'Content-Type': 'application/octet-stream',
                    'X-Requested-With':'XMLHttpRequest'
                })
                .then((res) => {
                    // the temp file path
                    CameraRoll.saveToCameraRoll('file://'+res.path()).then(() => {
                        this.props.onSave("android保存成功");
                        this.deleteCacheImage(res.path());
                    }).catch((err) => {
                        this.props.onSave(err);
                        this.deleteCacheImage(res.path());
                    });
                })
                .catch((error) => {
                    console.error(error);
                })
        }else if(Platform.OS === 'ios' && url.length > 0){
            CameraRoll.saveToCameraRoll(url).then(() => {
                this.props.onSave("ios保存成功");
            }).catch((err) => {
                this.props.onSave(err);
            });
        }

        this.setState({ isShowMenu: false });
    };

    getMenu() {
        if (!this.state.isShowMenu) {
            return null;
        }

        return (
            <View style={this.styles.menuContainer}>
                <View style={this.styles.menuShadow} />
                <View style={this.styles.menuContent}>
                    <TouchableHighlight
                        underlayColor="#F2F2F2"
                        onPress={this.saveToLocal}
                        style={this.styles.operateContainer}
                    >
                        <Label labelStyle={[this.styles.operateText]} type={'form'} color={'navbar'}  text={this.props.menuContext.saveToLocal} />
                    </TouchableHighlight>
                    <TouchableHighlight
                        underlayColor="#F2F2F2"
                        onPress={this.handleLeaveMenu}
                        style={this.styles.operateContainer}
                    >
                        <Label labelStyle={[this.styles.operateText]} type={'form'} color={'navbar'}  text={this.props.menuContext.cancel} />
                    </TouchableHighlight>
                </View>
            </View>
        );
    }

    handleLeaveMenu = () => {
        this.setState({ isShowMenu: false });
    };

    handleSwipeDown = () => {
        if (this.props.onSwipeDown) {
            this.props.onSwipeDown();
        }
        this.handleCancel();
    };

    render() {

        let childs = (
            <View>
                {this.getContent()}
                {this.getMenu()}
            </View>
        );

        return (
            <View
                onLayout={this.handleLayout}
                style={{ flex: 1, overflow: "hidden", ...this.props.style }}
            >
                {childs}
            </View>
        );
    }
}
const styles = (width, height, backgroundColor)=> (
    {
        modalContainer: {
            backgroundColor: backgroundColor,
            justifyContent: "center",
            alignItems: "center",
            overflow: "hidden"
        },
        watchOrigin: {
            position: "absolute",
            width: width,
            bottom: 20,
            justifyContent: "center",
            alignItems: "center"
        },
        watchOriginTouchable: {
            paddingLeft: 10,
            paddingRight: 10,
            paddingTop: 5,
            paddingBottom: 5,
            borderRadius: 30,
            borderColor: "white",
            borderWidth: 0.5,
            backgroundColor: "rgba(0, 0, 0, 0.1)"
        },
        watchOriginText: {
            color: "white",
            backgroundColor: "transparent"
        },
        imageStyle: {},
        container: {
            backgroundColor: backgroundColor
        },
        // 多图浏览需要调整整体位置的盒子
        moveBox: {
            flexDirection: "row",
            alignItems: "center"
        },
        menuContainer: {
            position: "absolute",
            width: width,
            height: height,
            left: 0,
            bottom: 0,
            zIndex: 100
        },
        menuShadow: {
            position: "absolute",
            width:width,
            height:height,
            backgroundColor: "black",
            left: 0,
            bottom: 0,
            opacity: 0.2,
            zIndex: 10
        },
        menuContent: {
            position: "absolute",
            width:width,
            left: 0,
            bottom: 0,
            zIndex: 11
        },
        operateContainer: {
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "white",
            height: 40,
            borderBottomColor: "#ccc",
            borderBottomWidth: 1
        },
        operateText: {
            color: "#333"
        },
        loadingTouchable: {
            width:width,
            height:height,
        },
        loadingContainer: {
            justifyContent: "center",
            alignItems: "center"
        },
        arrowLeftContainer: {
            position: "absolute",
            top: 0,
            bottom: 0,
            left: 0,
            justifyContent: "center",
            //zIndex: 100
        },
        arrowRightContainer: {
            position: "absolute",
            top: 0,
            bottom: 0,
            right: 0,
            justifyContent: "center",
           // zIndex: 100
        },
        saveContainer: {
            width: 45,
            height: 35,
            paddingBottom: 15,
            paddingRight: 15
        },
        headerContainer: {
            position: 'absolute',
            left: 0,
            right: 0,
            top: 30
        }
    }
)

const simpleStyle = StyleSheet.create({
    count: {
        position: "absolute",
        left: 0,
        right: 0,
        top: 15,
        backgroundColor: "transparent",
        flexDirection:'row'
    },
    countText: {
        color: "white",
        fontSize: 15,
        backgroundColor: "transparent",
        textShadowColor: "rgba(0, 0, 0, 0.3)",
        textShadowOffset: {
            width: 0,
            height: 0.5
        },
        textShadowRadius: 0
    },
    footer : {
        bottom: 0,
        position: "absolute",
        zIndex: 99,
        flexDirection:'row',
        alignItems:'flex-end',
        right:0,
        left:0
    }
})
ImageViewer.propTypes = {
    /**
     * 图片数组
     */
    imageUrls: PropTypes.array.isRequired,

    /**
     * 滑动到下一页的X阈值
     */
    flipThreshold: PropTypes.number,

    /**
     * 当前页能滑到下一页X位置最大值
     */
    maxOverflow: PropTypes.number,

    /**
     * 初始显示第几张图
     */
    index: PropTypes.number,

    /**
     * 加载失败的图
     */
    failImageSource: PropTypes.oneOfType([PropTypes.string,PropTypes.object]),

    /**
     * 背景颜色
     */
    backgroundColor: PropTypes.string,

    /**
     * style props for the footer container
     */
    footerContainerStyle: PropTypes.object,

    /**
     * Menu Context Values
     */
    menuContext: PropTypes.object,

    /**
     * 是否开启长按保存到本地的功能
     */
    saveToLocalByLongPress: PropTypes.bool,

    // style: View.propTypes.style,

    /**
     * 长按图片的回调
     */
    onLongPress: PropTypes.func,

    /**
     * 单击回调
     */
    onClick: PropTypes.func,

    /**
     * 双击回调
     */
    onDoubleClick: PropTypes.func,

    /**
     * 图片保存到本地方法，如果写了这个方法，就不会调取系统默认方法
     * 针对安卓不支持 saveToCameraRoll 远程图片，可以在安卓调用此回调，调用安卓原生接口
     */
    onSave: PropTypes.func,
    /**
     * 自定义头部
     */
    renderHeader: PropTypes.func,

    /**
     * 自定义尾部
     */
    renderFooter: PropTypes.func,

    /**
     * 自定义计时器
     */
    renderIndicator: PropTypes.func,

    /**
     * Render image component
     */
    renderImage: PropTypes.func,

    /**
     * 自定义左翻页按钮
     */
    renderArrowLeft: PropTypes.func,

    /**
     * 自定义右翻页按钮
     */
    renderArrowRight: PropTypes.func,

    /**
     * 弹出大图的回调
     */
    onShowModal: PropTypes.func,

    /**
     * 取消看图的回调
     */
    onCancel: PropTypes.func,

    /**
     * function that fires when user swipes down
     */
    onSwipeDown: PropTypes.func,

    /**
     * 渲染loading元素
     */
    loadingRender: PropTypes.func,

    /**
     * 当图片切换时触发
     */
    onChange: PropTypes.func

}
ImageViewer.defaultProps={
    flipThreshold: 80,
    maxOverflow: 300,
    index: 0,
    failImageSource: '',
    backgroundColor: "black",
    footerContainerStyle: {},
    menuContext: {
        saveToLocal: "保存",
        cancel: "取消"
    },
    /**
     * 是否开启长按保存到本地的功能
     */
    saveToLocalByLongPress: true,

    style: {},

    /**
     * 长按图片的回调
     */
    onLongPress: () => {
        //
    },

    /**
     * 单击回调
     */
    onClick: (onCancel) => {onCancel()},

    /**
     * 双击回调
     */
    onDoubleClick: (onCancel) => {onCancel()},

    /**
     * 图片保存到本地方法，如果写了这个方法，就不会调取系统默认方法
     * 针对安卓不支持 saveToCameraRoll 远程图片，可以在安卓调用此回调，调用安卓原生接口
     */
    //onSave: () => {},

    /**
     * 自定义头部
     */
    renderHeader: (currentIndex) => {
        return null
    },

    /**
     * 自定义尾部
     */
    renderFooter: (currentIndex) => {
        return null
    },

    /**
     * 自定义计数器
     */
    renderIndicator: (currentIndex, allSize, fileName) => {
        return React.createElement(
            View,
            { style: Calculate.isIphoneX() ? [simpleStyle.count,{top:40}, Platform.OS == 'harmony' &&{ zIndex:1 }] : [simpleStyle.count, Platform.OS == 'harmony' &&{ zIndex:1 }] },
            [React.createElement(
                Text,
                { key:'left',style: [simpleStyle.countText,{flex:1,alignItems:'center'}] },

            ),React.createElement(
                Text,
                { key:'fileName',style: [simpleStyle.countText,{flex:1,textAlign:'center'}] },
                fileName
            ),React.createElement(
                View,
                {key:'right',style:{flex:1}},
                [React.createElement(
                    Text,
                    { key:'count',style: [simpleStyle.countText,{flex:1,textAlign:'right',paddingRight:20}]},
                    currentIndex + "/" + allSize
                )]
            )]
        )
    },

    /**
     * Render image component
     */
    renderImage: (props) => {
        return React.createElement(Image, props)
    },

    /**
     * 自定义左翻页按钮
     */
    renderArrowLeft: () => {
        return null
    },

    /**
     * 自定义右翻页按钮
     */
    renderArrowRight: () => {
        return null
    },

    /**
     * 弹出大图的回调
     */
    onShowModal: (content) => {},

    /**
     * 取消看图的回调
     */
    onCancel: () => {},

    /**
     * function that fires when user swipes down
     */
    onSwipeDown: () => {
        //
    },

    /**
     * 渲染loading元素
     */
    loadingRender: () => {
        return null
    },

    /**
     * 当图片切换时触发
     */
    onChange: (index) => {}
}
